package com.umakr.ax.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @author umakr
 */
public final class Request2ListUtil {
	private Request2ListUtil() {
	}
	protected static final Log logger = LogFactory.getLog(Request2ListUtil.class);
	private static final Integer paramSize(Set<Method> methodSet, Map<String, String[]> stringMap) {
		Integer size = 0;
		for (Method method : methodSet) {
			String key = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
			Integer tempSize = 0;
			if (stringMap.containsKey(key)) {
				tempSize = stringMap.get(key).length;
			}
			if (tempSize > size) {
				size = tempSize;
			}
		}
		return size;
	}

	public static final <K> List<K> covert(Class<K> t, HttpServletRequest request) {
		try {

			List<K> objectList = new LinkedList<>();
			// 获取类的方法集合
			Set<Method> methodSet = getDeclaredMethods(t);
			Map<String, String[]> stringMap = request.getParameterMap();
			Integer valueSize = paramSize(methodSet, stringMap);
			logger.info(t.getName() + " Max Length:" + valueSize);
			for (int i = 0; i < valueSize; i++) {
				K object = t.newInstance();
				for (Method method : methodSet) {
					String key = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
					String[] value = stringMap.get(key);
					if (value != null && i < value.length) {
						Class<?>[] type = method.getParameterTypes();
						Object[] paramValue = new Object[] { TypeParseUtil.convert(value[i], type[0], null) };
						method.invoke(object, paramValue);
					}
				}
				objectList.add(object);
			}
			return objectList;
		} catch (Exception ex) {
			logger.debug(ex);
		}
		return null;
	}

	/**
	 * 取自定义Set方法
	 *
	 * @param t
	 * @return
	 */
	private static final <T> Set<Method> getDeclaredMethods(Class<T> t) {
		Method[] methods = t.getDeclaredMethods();
		Set<Method> methodSet = new HashSet<>();
		for (Method method : methods) {
			if (method.getName().startsWith("set")) {
				methodSet.add(method);
			}
		}
		return methodSet;
	}
}
